package liquor.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import liquor.collection.RoundRobin;
import liquor.constant.DateConstants;
import liquor.exception.LiquorException;

public class DateUtil {
	
	private static final RoundRobin<Integer> RR_QUARTER
		= new RoundRobin<Integer>(
			  DateConstants.QUARTER_FIRST
			, DateConstants.QUARTER_SECOND
			, DateConstants.QUARTER_THRID
			, DateConstants.QUARTER_FOURTH
		);
	
	private static Map<String, SimpleDateFormat> dateFormatterMap = null;
		
	
	private static SimpleDateFormat getSimpleDateFormat(String pattern) {
		if (dateFormatterMap == null) {
			dateFormatterMap = new HashMap<String, SimpleDateFormat>();
		}
		
		SimpleDateFormat formatter = dateFormatterMap.get(pattern);
		if (formatter == null) {
			formatter = new SimpleDateFormat(pattern);
			dateFormatterMap.put(pattern, formatter);
		}
		
		return formatter;
	}
	
	private static Calendar getCalender(String date, String pattern) {
		Calendar calendar = Calendar.getInstance();
		try {		
			SimpleDateFormat sdf = DateUtil.getSimpleDateFormat(pattern);
			Date d = sdf.parse(date);
		
			calendar.setTime(d);
		} catch (ParseException e) {
			throw new LiquorException(e.getMessage());
		}
		
		return calendar;
	}
	
	/**
	 * 입력으로 들어온 날짜 (yyyyMMdd)의 분기값을 계산해준다
	 * 
	 * @param date 날짜 (yyyyMMdd형)
	 * @return 분기
	 * @throws ParseException
	 */
	public static int getQuarter(String date) {
		return DateUtil.getQuarter(date, DateConstants.DATE_FORMAT_DEFAULT);
	}
	
	/**
	 * 입력으로 들어온 날짜의 분기값을 계산해준다
	 * 
	 * @param date 날짜
	 * @param pattern 날짜의 형식 {@link DateConstants}의 날짜 지원형태
	 * @return 분기
	 * @throws ParseException
	 */
	public static int getQuarter(String date, String pattern) {
		Calendar calendar = DateUtil.getCalender(date, pattern);
		
		int month = calendar.get(Calendar.MONTH)+1;
		
		return ((month-1)/3)+1;
	}
	
	/**
	 * 입력으로 들어온 분기의 다음 분기를 계산한다
	 * 
	 * @param currentQuarter 현재분기값
	 * @return 다음분기
	 */
	public static int getNextQuarter(int currentQuarter) {
		return RR_QUARTER.next(currentQuarter);
	}
	
	/**
	 * 입력으로 들어온 분기의 다음 분기를 계산한다
	 * 
	 * @param date 날짜 (yyyyMMdd형)
	 * @return 다음분기
	 */
	public static int getNextQuarter(String date) {
		return RR_QUARTER.next(DateUtil.getQuarter(date));
	}
	
	/**
	 * 입력으로 들어온 분기의 다음 분기를 계산한다
	 * 
	 * @param date 날짜 (yyyyMMdd형)
	 * @param pattern 날짜의 형식 {@link DateConstants}의 날짜 지원형태
	 * @return 다음분기
	 */
	public static int getNextQuarter(String date, String pattern) {
		return RR_QUARTER.next(DateUtil.getQuarter(date, pattern));
	}
		
	/**
	 * 입력으로 들어온 분기의 이전 분기를 계산한다
	 * 
	 * @param currentQuarter 현재분기값
	 * @return 다음분기
	 */
	public static int getBeforeQuarter(int currentQuarter) {
		return RR_QUARTER.before(currentQuarter);
	}
	
	/**
	 * 입력으로 들어온 분기의 이전 분기를 계산한다
	 * 
	 * @param date 날짜 (yyyyMMdd형)
	 * @return 다음분기
	 */
	public static int getBeforeQuarter(String date) {
		return RR_QUARTER.before(DateUtil.getQuarter(date));
	}
	
	/**
	 * 입력으로 들어온 분기의 이전 분기를 계산한다
	 * 
	 * @param date 날짜 (yyyyMMdd형)
	 * @param pattern 날짜의 형식 {@link DateConstants}의 날짜 지원형태
	 * @return 다음분기
	 */
	public static int getBeforeQuarter(String date, String pattern) {
		return RR_QUARTER.before(DateUtil.getQuarter(date, pattern));
	}
	
	
}
